package com.example.thread.demo.completablefuture;

import com.example.thread.demo.util.ExecutorServiceUtil;

import java.util.concurrent.*;

/**
 * @author zhy
 * @date 2020/5/18 6:38 下午
 * @description 举一个生活上的例子，假如我们需要出去旅游，需要完成三个任务：任务一：订购航班，任务二：订购酒店，任务三：订购租车服务
 * 很显然任务一和任务二没有相关性，可以单独执行。但是任务三必须等待任务一与任务二结束之后，才能订购租车服务。
 * 为了使任务三时执行时能获取到任务一与任务二执行结果，我们还需要借助 CountDownLatch 。
 */
public class CountDownLatchTest {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executorService = ExecutorServiceUtil.newThreadPool();
        CountDownLatch countDownLatch = new CountDownLatch(2);

        // 任务1 预定航班
        Future<String> orderAirplane = executorService.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("查询航班");
                Thread.sleep(3000);
                System.out.println("订购航班");
                countDownLatch.countDown();
                return "航班号";
            }
        });

        // 任务2 预定酒店
        Future<String> orderHotel = executorService.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("查询酒店");
                Thread.sleep(3000);
                System.out.println("订购酒店");
                countDownLatch.countDown();
                return "酒店";
            }
        });

        // 使用 countDownLatch 等待 任务1 与 任务2 完成
        countDownLatch.await();

        Future<String> orderCar = executorService.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("根据航班和酒店订购租车服务");
                Thread.sleep(5000);
                return "租车信息";
            }
        });

        System.out.println(orderCar.get());

    }
}
